/**
 * jstat使用教程
 * 对应案例五
 * -XX:NewSize=104857600 -XX:MaxNewSize=104857600 -XX:InitialHeapSize=209715200 -XX:MaxHeapSize=209715200 -XX:SurvivorRatio=8  -XX:MaxTenuringThreshold=15 -XX:PretenureSizeThreshold=3145728 -XX:+UseParNewGC -XX:+UseConcMarkSweepGC -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -Xloggc:gc.log
 * 不用画图
 */
public class JstatUseDemo1 {
    public static void main(String[] args) throws InterruptedException {
        Thread.sleep(30000);
        while (true){
            loadData();
        }
    }

    private static void loadData() throws InterruptedException {
        byte [] data = null;
        for(int i=0;i<50;i++){
            data = new byte[100*1024];
        }
        data=null;
        Thread.sleep(1000);
    }

    /**
     * 首先看第一行代码：Thread.sleep(30000);
     * 为什么刚开始先休眠30s？
     * 因为一会儿会告诉大家，程序刚启动，必须得先让我们找到这个程序的PID，也就是进程ID，然后再执行jstat命令来观察程序运行时JVM的状态。
     * 接着看loadData()方法内的代码，其实非常简单，他会循环50次，模拟每秒50个请求
     * 然后每次请求会分配一个100KB的数组，模拟每次请求会从数据存储中加载出来100KB的数据。接着会休眠1秒钟，模拟这一切都是发生在1秒内的。
     * 其实这些对象都是短生存周期的对象，所以方法运行结束直接对象都是垃圾，随时可以回收的。
     * 然后在main()方法里有一个while(true)循环，模拟系统按照每秒钟50个请求，每个请求加载100KB数据的方式不停的运行，除非我们手动终止程序，否则永不停歇。
     * 这个EU大家应该还记得，就是之前我们所说的Eden区被使用的容量，可以发现他刚开始是3MB左右的内存使用量
     * 接着从我们程序开始运行，会发现每秒钟都会有对象增长，从3MB左右到7MB左右，接着是12MB，17MB，22MB，每秒都会新增5MB左右的对象。
     * 这个跟我们写的代码是完全吻合的，我们就是每秒钟会增加5mB左右的对象。
     * 然后当Eden区使用量达到70多MB的时候，再要分配5MB的对象就失败了，此时就会触发一次Young GC，
     * 大家会发现，Eden区的使用量从70多MB降低为了1MB多，这就是因为一次Young GC直接回收掉了大部分对象。
     * 所以我们现在就知道了，针对这个代码示例，可以清晰的从jstat中看出来，对象增速大致为每秒5MB左右，大致在十几秒左右会触发一次Young GC
     *
     * 所以你想如果是线上系统，他Eden区800MB的话，每秒新增对象50MB，十多秒一次Young GC，也就10毫秒左右，系统卡顿10毫秒，几乎没什么大影响的。
     * 老年代的内存占用一直为0
     * 这说明这个系统运行良好，Young GC都不会导致对象进入老年代，这就几乎不需要什么优化了。因为几乎可以默认老年代对象增速为0，Full  GC发生频率趋向于0，对系统无影响。
     */
}
